/// @Classname : HcProgress
/// @Author :
/// @Time : 2023-09-14 11:08
/// @Description : //todo

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:hc_ui/utils/hc_gradient_util.dart';
import 'package:hc_ui/utils/hc_number_util.dart';
import 'package:hc_ui/utils/hc_string_util.dart';
import 'package:hc_ui/widget/icon_text/hc_icon_text.dart';

class HcPiecewiseColorItem {
  double percentage;
  Color color;

  HcPiecewiseColorItem({required this.percentage, required this.color});
}

enum HcProgressTextPosition {
  //左上
  leftTop,
  //右上
  rightTop,
  //顶部剧中
  topCenter,
  //左下
  leftBottom,
  //右下
  rightBottom,
  //下部居中
  bottomCenter,
  //左侧
  centerLeft,
  //右侧
  centerRight,
//  居中
  center,
  //内部
  inside,
  //顶部跟随
  topFlow,
  //中部跟随
  insideFlow,
  //底部跟随
  bottomFlow,
  //不显示
  none,
}

class HcProgress extends StatelessWidget {
  //当前进度0-100之间
  final double value;

  //轨道背景颜色
  final Color bgColor;

  //进度条颜色
  final Color color;

  //背景渐变
  final Gradient? gradient;

  //圆角弧度
  final double radius;

  //高度
  final double height;

  //分段颜色展示列表
  final List<HcPiecewiseColorItem>? piecewiseList;

  //进度文字显示位置
  final HcProgressTextPosition textPosition;

  //是否展示斜线
  final bool showStripe;

  //提示的文字
  final String? tips;

  //提示文字的样式
  final TextStyle? tipsStyle;

  //边框的样式
  final Border? border;

  //活动的 Icon
  final Widget? activeIcon;

  //内边距
  final EdgeInsets padding;

  //文字和进度条间隔
  final double spacing;

  //动画时长
  final Duration duration;

  //保留几位小数字
  final int decimal;
  final Curve curve;

  const HcProgress(
      {super.key,
      required this.value,
      this.bgColor = const Color(0xffe7e7e7),
      this.color = Colors.blue,
      this.radius = 0,
      this.height = 12,
      this.textPosition = HcProgressTextPosition.inside,
      this.gradient,
      this.piecewiseList,
      this.showStripe = false,
      this.tips,
      this.tipsStyle,
      this.border,
      this.activeIcon,
      this.padding = const EdgeInsets.symmetric(vertical: 2, horizontal: 8),
      this.spacing = 0,
      this.duration = const Duration(milliseconds: 1000),
      this.decimal = 2,
      this.curve = Curves.decelerate});

  @override
  Widget build(BuildContext context) {
    //转换成字符串
    double num = 0;
    num = min(100, max(0, value));
    String percentageStr =
        tips ?? '${HcNumberUtil.formatNum(num: num, position: decimal)}%';
    Size size = HcStringUtil.boundingTextSize(
        context,
        percentageStr.contains("%") && percentageStr.length == 2
            ? '0$percentageStr'
            : percentageStr,
        tipsStyle ?? TextStyle(fontSize: height),
        maxLines: 1);
    double textWidth = size.width;
    double finalHeight = max(tipsStyle?.fontSize ?? 14.0, height);
    //判断对齐方式
    CrossAxisAlignment alignment;
    if (textPosition.toString().contains('right')) {
      alignment = CrossAxisAlignment.end;
    } else if (textPosition.toString().contains('left')) {
      alignment = CrossAxisAlignment.start;
    } else {
      alignment = CrossAxisAlignment.center;
    }
    //判断颜色
    Color finalColor = color;
    List<HcPiecewiseColorItem> temp = [
      HcPiecewiseColorItem(percentage: 0, color: color)
    ];
    if (piecewiseList != null && piecewiseList!.isNotEmpty) {
      temp.addAll(piecewiseList as Iterable<HcPiecewiseColorItem>);
    }
    temp = temp.where((element) => element.percentage <= num).toList();
    finalColor = temp.last.color;

    bool isVertical = false;
    if (textPosition != HcProgressTextPosition.centerRight &&
        textPosition != HcProgressTextPosition.centerLeft) {
      isVertical = true;
    }

    return Padding(
      padding: activeIcon != null
          ? padding.copyWith(
              top: padding.top + finalHeight,
              bottom: padding.bottom + finalHeight)
          : padding,
      child: HcIconText(
        spacing: spacing,
        mainAxisAlignment: MainAxisAlignment.center,
        reverse: textPosition.toString().toLowerCase().contains('top') ||
            textPosition == HcProgressTextPosition.centerLeft,
        direction: isVertical ? Axis.vertical : Axis.horizontal,
        crossAxisAlignment: alignment,
        //构建进度条部分
        icon: Flexible(
          child: _progressBar(
              context, finalHeight, textWidth, num, percentageStr, finalColor),
        ),
        //进度条文字部分
        label: _buildPercentText(
          textPosition.index < 8 ? percentageStr : '',
        ),
      ),
    );
  }

  //构建进度条
  Widget _progressBar(context, double finalHeight, double textWidth, double num,
      String percentageStr, finalColor) {
    //背景颜色和边框部分
    return Container(
        width: double.infinity,
        decoration: BoxDecoration(
          border: border,
          borderRadius: BorderRadius.circular(radius),
          color: bgColor,
        ),
        child: LayoutBuilder(builder: (content, container) {
          // 最大的宽度
          double maxWidth = container.maxWidth;
          double iconSize = finalHeight * 3;
          double halfIconSize = double.parse(
              HcNumberUtil.formatNum(num: iconSize / 2, position: decimal));
          // 所占百分比
          double percent = double.parse(
              HcNumberUtil.formatNum(num: num / 100, position: decimal));
          // 当前实际宽度
          double currentWidth = double.parse(HcNumberUtil.formatNum(
              num: maxWidth * percent, position: decimal));
          //是否展示头部图标 仅在有图标且进度超过图标的一半和不超过全部宽度时展示
          bool isShowActiveIcon = activeIcon != null &&
              (currentWidth >= halfIconSize) &&
              (currentWidth + halfIconSize <= maxWidth);
          bool showInsideText =
              textPosition.toString().toLowerCase().contains("inside");
          // dart计算精度有问题需要手动修复
          currentWidth = double.parse(HcNumberUtil.formatNum(
              num: currentWidth - (isShowActiveIcon ? halfIconSize : 0),
              position: decimal));
          currentWidth = min(container.maxWidth, currentWidth);
          return Stack(
            clipBehavior: Clip.none,
            alignment: Alignment.topLeft,
            children: [
              //进度条滚动部分
              ClipRRect(
                borderRadius: BorderRadius.circular(radius),
                child: AnimatedContainer(
                  curve: curve,
                  constraints: BoxConstraints(minHeight: finalHeight),
                  width: currentWidth,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(radius),
                    color: finalColor,
                    gradient: gradient,
                  ),
                  foregroundDecoration: BoxDecoration(
                    gradient: num > 0 && showStripe
                        ? HcGradientUtil.generateLinearGradient(
                            colors: [
                                const Color.fromRGBO(255, 255, 255, 0.15),
                                Colors.transparent,
                                Colors.transparent,
                                const Color.fromRGBO(255, 255, 255, 0.15),
                                const Color.fromRGBO(255, 255, 255, 0.15),
                                Colors.transparent,
                                Colors.transparent,
                              ],
                            stops: [
                                0.25,
                                0.25,
                                0.5,
                                0.5,
                                0.75,
                                0.75,
                                1
                              ],
                            degree: 45,
                            width: double.parse(HcNumberUtil.formatNum(
                                num: finalHeight / currentWidth,
                                position: decimal)),
                            tileMode: TileMode.repeated)
                        : null,
                  ),
                  duration: duration,
                  child:
                      //    需要在进度条活动的内部展示走这里
                      Align(
                    alignment: textPosition == HcProgressTextPosition.insideFlow
                        ? Alignment.topRight
                        : Alignment.center,
                    child: _buildPercentText(
                      showInsideText && textWidth < currentWidth
                          ? percentageStr
                          : '',
                    ),
                  ),
                ),
              ),
              //当进度条不足以容纳显示内部文字时
              if (showInsideText && textWidth > currentWidth)
                AnimatedPositioned(
                  left: currentWidth + (isShowActiveIcon ? iconSize : 0),
                  duration: duration,
                  curve: curve,
                  child: _buildPercentText(percentageStr),
                ),

              //头部活动按钮
              if (activeIcon != null)
                AnimatedPositioned(
                  curve: curve,
                  duration: duration,
                  top: -finalHeight,
                  left: max(0, currentWidth),
                  child: AnimatedOpacity(
                    opacity: isShowActiveIcon ? 1 : 0,
                    duration: duration,
                    child: IconTheme(
                      data: Theme.of(context)
                          .iconTheme
                          .copyWith(size: iconSize, color: finalColor),
                      child:activeIcon!,
                    ),
                  ),
                ),
              if (textPosition == HcProgressTextPosition.topFlow ||
                  textPosition == HcProgressTextPosition.bottomFlow)
                AnimatedPositioned(
                  curve: curve,
                  duration: duration,
                  top: (textPosition.toString().toLowerCase().contains("top")
                          ? -1
                          : 1) *
                      (finalHeight +
                          spacing +
                          (isShowActiveIcon ? finalHeight : 0)),
                  left: min(
                      maxWidth - textWidth,
                      max(
                          0,
                          currentWidth -
                              double.parse(HcNumberUtil.formatNum(
                                  num: textWidth / 2, position: decimal)) +
                              (isShowActiveIcon ? halfIconSize : 0))),
                  child: _buildPercentText(
                    percentageStr,
                  ),
                ),
              //在整个进度条最中央显示整个
              if (textPosition == HcProgressTextPosition.center)
                Center(
                  child: _buildPercentText(percentageStr),
                )
            ],
          );
        }));
  }

  Widget _buildPercentText(String percentageStr) {
    return Text(
      percentageStr,
      maxLines: 1,overflow: TextOverflow.ellipsis,
      style: tipsStyle ?? TextStyle(fontSize: height),
    );
  }
}
